package monopolyServlet;

import ClientBL.Event;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import net.sf.json.JSONObject;
import GameServer.ServerService;
import Monopol.MonopolExceptions.MonopolErrors;
import Monopol.Events.MonopolyGameEvents;
import Monopol.MonopolyGame;
import Utils.GameDetails;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Servlet implementation class MonopolyServlet
 */
public class MonopolyServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;
    // Constants
    // Page Response and Forwards
    private static final String GAME_LOADER_PAGE = "/loadPage.jsp";
    private static final String GAME_JOIN_PAGE = "/joinPage.jsp";
    private static final String GAME_PLAY_PAGE = "/playGame.jsp";
    private static final String GAME_WAIT_PAGE = "/waitPage.jsp";
    public static final String CONTENT_TYPE_JSON = "application/json;charset=UTF-8";
    public static final String CONTENT_TYPE_TEXT = "text/plain";
    public static final String CONTENT_TYPE_HTML = "text/html;charset=UTF-8";
    private static final String ERROR_MESSAGE = "errMsg";
    // Game Status
    private static final String ACTIVE_GAME = "ACTIVE";
    private static final String WAITING_GAME = "WAITING";
    // Load Page Inputs
    private static final String GAME_NAME = "gameName";
    private static final String PLAYER_NAME = "playerName";
    private static final String NUM_OF_PLAYERS = "nPlayers";
    private static final String NUM_OF_HUMANS = "nhPlayers";
    private static final String AUTO_DICE_MODE = "autoDice";
    private static final String JOINED_HUMANS = "joinedPlayers";
    // Player Constants
    private static final String PLAYER_ID = "playerID";
    // Request Actions
    private static final String GET_ACTION = "action";
    private static final String GET_STATE = "state";
    private static final String BUY_ASSET_ACTION = "asset";
    private static final String BUY_HOUSE_ACTION = "house";
    private static final String CUBES_ACTION = "dices";
    private static final String QUIT_ACTION = "quit";
    private static final String REDIRECT_ACTION = "redirect";
    // Messages
    private static final String MSG_ACTIVE_GAME = "You can not join an Active Game";
    private static final String MSG_INVALID_NAME = "The Player Name you chose is Invalid.<BR>"
	    + "Enter a new Player Name.";
    private static final String MSG_GAME_END = "Sorry... <BR>The Game Is Over."
	    + "<BR>You can create a new game now! <img src='../img/smielly.jpg' height='64px' width='64px'>";
    // Variables
    private static boolean gameEnd = false;
    private GameDetails gameDetails;
    private static Boolean answer;// contain answer received from user
    private static ArrayList<JSONObject> jEvents;// contains all events received
    private static Integer[] cubes;// contain cubes answered values
    private static Boolean waiting = true;// used internally indicating waiting
    private Monopol.MonopolyGame monopolyGame;//creating the game container
    private List<Event> events;

    // for input from user
    /**
     * Inner class for managing the Web client info
     */
    private class WebClientInformation {

	Integer json_index;
	Integer playerID;

	public WebClientInformation(Integer json_index, Integer playerID) {
	    this.playerID = playerID;
	    this.json_index = json_index;
	}

	public Integer getEvent() {
	    return this.json_index;
	}

	public void setEventID(Integer newEventID) {
	    this.json_index = newEventID;
	}
    }

    @Override
    public void init() throws ServletException {
	super.init();
	getGameDetails();
	StartJsonFeed();
    }

    /**
     * Sets the {@link GameDetails} Object with the Current Monopoly Games in the Server
     */
    private void getGameDetails() {
	// Get all the Monopoly Games in the server
	ArrayList<GameDetails> monopolyGames = getMonopolyGames();
	// Check the games array
	if (monopolyGames.isEmpty()) {
	    // No games - Empty list
	    gameDetails = null;
	} else {
	    // We are supporting only one game there for we will select the
	    // first game from all the games in the server
	    gameDetails = monopolyGames.get(0);
	}
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doGet(HttpServletRequest request,
	    HttpServletResponse response) throws ServletException, IOException {
	processRequest(request, response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
     *      response)
     */
    protected void doPost(HttpServletRequest request,
	    HttpServletResponse response) throws ServletException, IOException {
	processRequest(request, response);
    }

    /**
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    private void processRequest(HttpServletRequest request,
	    HttpServletResponse response) throws ServletException, IOException {
	// Set a cookie for the user
	HttpSession session = request.getSession(true);
	// Set the session valid for 5 secs
	session.setMaxInactiveInterval(60);
	// no caching!
	response.setHeader("Cache-Control", "no-cache"); // HTTP 1.1
	response.setHeader("Pragma", "no-cache"); // HTTP 1.0
	response.setDateHeader("Expires", 0); // prevents caching at the proxy server
	// Get the Game Name
	String gameName = request.getParameter(GAME_NAME);
	// Check if there is Game
	if (gameDetails != null) {
	    // Check if the Game is in Waiting mode
	    if (gameDetails.getGameStatus().equals(WAITING_GAME)) {
		// Check the Status of the Monpoly Game
		initMonopolyGame(gameDetails.getGameName(), gameDetails.getTotalPlayers());
		// Check if this is the First time the Page is Loaded - Joinning a new Player
		if (request.getParameter(PLAYER_NAME) == null) {
		    System.out.println("Join Player to game");
		    // Join the User to the Game
		    forwardToJoinPage(request, response); // Forward to Join game
		} else {
		    // This is a Players responce for Joinning the Game - Add it to the Game
		    // Join the User to the Game
		    if (!joinPlayerToGame(session, gameDetails.getGameName(), (String) request.getParameter(PLAYER_NAME))) {
			sendError(request, response, MSG_INVALID_NAME);
		    }
		    // Update Players - After this Player Was Added
		    monopolyGame.updatePlayers(gameDetails.getGameName(), gameDetails.getTotalPlayers());
		    // Forward to Playing Game
		    forwardToPlayGame(request, response, gameName);
		}
	    } else { //  if (gameDetails.getGameStatus() == ACTIVE_GAME) {
		// Check if User has a Playing Session
		if (checkPlayerSession(session)) {
		    // The Player is Playing - Process the game Request
		    processGameRequest(request, response);
		} else {
		    sendError(request, response, MSG_ACTIVE_GAME);
		}
	    }
	} else {
	    // There is no Game - Check the User Game Details
	    if (gameName == null || gameName.equals("null")) {
		// Forward the Page to a New Game Loader Page
		forwardToLoadPage(request, response);
	    } else {
		WebClientInformation clientInfo;
		try {
		    clientInfo = (WebClientInformation) session;
		} catch (ClassCastException e) {
		    clientInfo = null;
		}
		// Check if Player has a Valid Session
		if (clientInfo == null) {
		    // Create the Game and Join the User to the Game
		    createGame(request);
		    // Join the User to the Game
		    if (!joinPlayerToGame(session, gameName, (String) request.getParameter(PLAYER_NAME))) {
			sendError(request, response, MSG_INVALID_NAME);
		    }
		    // Initialize the Game Squares
//		    monopolyGame.initGameSquares();
		    // Update the Number of players after the Player was added to the game
		    monopolyGame.updatePlayers(gameName, getInt((String) request.getParameter(NUM_OF_PLAYERS)));
		    // Set the variable gameDetails with the current Game Details
		    getGameDetails();
		    // Forware the Player to the Game
		    forwardToPlayGame(request, response, (String) request.getParameter(PLAYER_NAME));
		} else {
		    // The Player is Playing - Process the game Request
		    processGameRequest(request, response);
		}
	    }
	}
	System.out.println("DEBUG: gameEnd Value " + Boolean.toString(gameEnd));
	// Check if the Game has Ended
	if (gameEnd) {
	    // Initialize the Game
	    gameDetails = null;
	    // Initialize the Game Events
	    events.clear();
	    System.out.println("Restarted the Game Details!");
	    // Initialize the Game End Flag
	    gameEnd = false;
	} else {
	    getGameDetails();
	}
    }

    /**
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    private void processGameRequest(HttpServletRequest request,
	    HttpServletResponse response) throws ServletException, IOException {
	JSONObject json;// will contain the JSON response
	response.setContentType(CONTENT_TYPE_JSON);
	// no caching!
	response.setHeader("Cache-Control", "no-cache"); // HTTP 1.1
	response.setHeader("Pragma", "no-cache"); // HTTP 1.0
	response.setDateHeader("Expires", 0); // prevents caching at the proxy
	// server
	PrintWriter out = response.getWriter();
	// Getting identification of the response sent
	String param = null;
	Integer playerID = getPlayerID(request);
	Integer eventID = getEventID(request);
	try {
	    param = request.getParameter(GET_ACTION);
	} catch (Exception e) {
	    System.out.println("Error:" + e.getMessage());
	}
	if (param != null) {
	    if (param.equals(CUBES_ACTION)) {// if the identifier was dices
		cubes = new Integer[2];
		// cubes value
		cubes[0] = getInt(request.getParameter("cube1"));// insert
		cubes[1] = getInt(request.getParameter("cube2"));
		// Setting the Player Cubes in Local Game
		monopolyGame.setPlayerCubes(cubes[0], cubes[1]);
		// Sending the Cubes to the Server
		MonopolyGameEvents.getInstance().setCubesEvent(playerID, eventID, cubes);
	    } else if (param.equals(QUIT_ACTION)) {// if the identifier was dices
		// gets the resigning player ID
		System.out.println("Player wants to Quit (" + playerID + ")");
		try {
		    // Make the Player Quit in the Game
		    //		String retMessage = monopolyGame.playerQuits(playerID);
		    MonopolyGameEvents.getInstance().setResignedPlayer(playerID);
		    System.out.println("DEBUG: Sent the Server a Message After Player Quits");
		} catch (MonopolErrors ex) {
		    Logger.getLogger(MonopolyServlet.class.getName()).log(Level.SEVERE, null, ex);
		}
		
	    } else if (param.equals(BUY_ASSET_ACTION)) {
		// answer was received after a dialog
		answer = getAnswerResult(request.getParameter("answer"));
		System.out.println("Asset Buy was answered " + answer);
		Boolean result;
		try {
		    // Send the Server an Event for the Buying the Asset (According to the Player Response)
		    result = MonopolyGameEvents.getInstance().setBuyAsset(playerID, eventID, answer);
		} catch (Exception ex) {
		    System.out.println("ERROR: Could not send Event to Server");
		}
	    } else if (param.equals(BUY_HOUSE_ACTION)) {
		// answer was received after a dialog
		answer = getAnswerResult(request.getParameter("answer"));
		System.out.println("House Buy was answered " + answer);
		Boolean result;
		try {
		    // Send the Server an Event for the Buying the House (According to the Player Response)
		    result = MonopolyGameEvents.getInstance().setBuyHouse(playerID, eventID, answer);
		} catch (Exception ex) {
		    System.out.println("ERROR: Could not send Event to Server");
		}
	    } else if (param.equals(REDIRECT_ACTION)) {
		forwardToLoadPage(request, response, MSG_GAME_END);
	    }
	}
	// Update the Server Events
	getServerEvents();
	// get client info form session
	WebClientInformation clientInfo = (WebClientInformation) request.getSession().getAttribute(PLAYER_ID);
	// response will be in JSON format
	response.setContentType(CONTENT_TYPE_JSON);
	response.setHeader("pragma-", "no-cache");
	// Check if the game is Started or posible to start
	// Accourding to the NUmber of Joined Human Players and Total Human Players
	if (checkPosibleStart()) {
	    if (clientInfo != null) {
		// Handle the Requested Player Event
		Integer reqEventID = clientInfo.getEvent();
		System.out.println("DEBUG: Requesting Event ID " + reqEventID);
		// Update the Current Event ID to an existsting Event in the Events Array
		reqEventID = parseServerEvent(reqEventID);
		System.out.println("DEBUG: Returned Event ID " + reqEventID);
		// Checks if JSON status are flowing from server side
		if (!jEvents.isEmpty()) {
		    try {
			// get relevant JSON
			json = jEvents.get(reqEventID);
			System.out.println("Printing JSON State");
			// Write the JSON
			out.println(json);
			// The Event was Sent successfully
			// Update the Event Id for this Player to the Next Event
			clientInfo.setEventID(reqEventID + 1);
		    } catch (Exception e) {
			System.out.println("ERROR: Could Not Send new JSON!");
			System.out.println("Requested Event ID: " + reqEventID);
			System.out.println("JSON Events Size: " + jEvents.size());
			System.out.println("Error Message: " + e.getMessage());
			// Set the Event Id for this Player to the Current Event
			clientInfo.setEventID(reqEventID);
		    }
		} else // if game is finished or not started and empty JSON will be sent
		{
		    System.out.println("no new events sending empty json");
		    out.println("");
		}
	    } else {
		System.out.println("Error: No Player Session!");
	    }
	}
	out.close();
	// Update the Server Events
	getServerEvents();
    }

    /**
     * Returns the Player ID from the Request Session
     * @param request The HTTP Request
     * @return The Player ID as {@link Integer}
     */
    private Integer getPlayerID(HttpServletRequest request) {
	try {
	    if (request.getSession() != null) {
		WebClientInformation clientInfo = (WebClientInformation) request.getSession().getAttribute(PLAYER_ID);
		return clientInfo.playerID;
	    } else {
		return null;
	    }
	} catch (ClassCastException e) {
	    System.out.println("No Session Web Client Info.");
	    return null;
	}
    }

    /**
     * Returns the Event ID Assigned to the Player
     * @param request The HTTP Request
     * @return The Event ID as {@link Integer}
     */
    private Integer getEventID(HttpServletRequest request) {
	try {
	    if (request.getSession() != null) {
		WebClientInformation clientInfo = (WebClientInformation) request.getSession().getAttribute(PLAYER_ID);
		return clientInfo.json_index - 1;
	    } else {
		return null;
	    }
	} catch (ClassCastException e) {
	    System.out.println("No Session Web Client Info.");
	    return null;
	}
    }

    private Boolean joinPlayerToGame(HttpSession session, String gameName,
	    String playerName) {
	Integer pID = -1;
	// Join the Player to the Game in the Server
	pID = ServerService.getInstance().joinPlayer(gameName, playerName);
	// Check that the server did not return an Error
	if (pID == -1) {
	    // The Player name is Invalid - Return false
	    return false;
	}
	try {
	    WebClientInformation clientInfo = new WebClientInformation(0, pID);
	    // Set the session ID as the Player name
	    session.setAttribute(PLAYER_ID, clientInfo);
	} catch (Exception e) {
	    // The Session must me Invalidated already
	    // The Users took to much time to initialize or respond
	    System.out.println("User Session has Ended!");
	}
	// The Player got a valid ID - Return true
	return true;
    }

    /**
     *
     * @return Returns all the Current Games in the Server
     */
    public ArrayList<GameDetails> getMonopolyGames() {
	ArrayList<GameDetails> arrMonopolyGames = new ArrayList<GameDetails>();
	try {
	    String[] waitingGames = ServerService.getInstance().getWaitingMonopolyGames();
	    String[] activeGames = ServerService.getInstance().getActiveMonopolyGames();
	    // Check if No Waiting Games And there are Active Games
	    if (waitingGames.length == 0 && activeGames.length > 0) {
		// Update the Active Games in the Table
		arrMonopolyGames.addAll(getGames(activeGames));
	    } else if (waitingGames.length > 0 && activeGames.length == 0) {
		// Update the Waiting Games in the Table
		arrMonopolyGames.addAll(getGames(waitingGames));
	    } else {
		// No Games - Return Null
	    }
	} catch (Exception e) {
	    System.out.println("Server Error, Can't get Monopoly Games!");
	}
	return arrMonopolyGames;
    }

    /**
     * Returns an Array of the Monopoly Games
     *
     * @param monopolyGames
     *            The Monopoly Games Names String Array
     * @return An Array of the Monopoly Games
     */
    private ArrayList<GameDetails> getGames(String[] monopolyGames) {
	ArrayList<GameDetails> arrGames = new ArrayList<GameDetails>();
	// For Each Game in the Monopoly Games
	for (String name : monopolyGames) {
	    // Get the Game Details for the Game
	    GameDetails gameDet = ServerService.getInstance().getGameDetails(name);
	    // In case the Game Exists in the Array - Catch the Exception
	    try {
		// Add the Games to the Array
		arrGames.add(gameDet);
	    } catch (Exception e) {
		e.printStackTrace();
	    }
	}
	return arrGames;
    }

    /**		
     * Checks and Initializes a Monpoly Game		
     * @param gameName		
     *	    The Game Name to check		
     * @param totalPlayers		
     *	    The Total Number of Players in the game		
     */
    private void initMonopolyGame(String gameName, Integer totalPlayers) {
	// Verify that the Monopoly Game Object is Initialized		
	if (monopolyGame == null) {
	    monopolyGame = new MonopolyGame();
	}
	// Verify that the Game Squares are Initialized		
	if (!monopolyGame.getGameSquaresStatus()) {
	    monopolyGame.initGameSquares();
	}
	// Verify that the Players are initialized		
	if (!monopolyGame.getGamePlayersStatus()) {
	    monopolyGame.updatePlayers(gameName, totalPlayers);
	}
    }

    /**		
     * Load Properly the Monopoly Game		
     * @param gameName		
     *	    The Game Name		
     * @param numOfHumans		
     *	    The Number Of Playing Humans		
     * @param numOfComputers		
     *	    The Number Of Playing Computers		
     * @param isAutoDice		
     *	    Is the Game Using Automatic Dice?		
     */
    private void loadMonopolyGame(String gameName, Integer numOfHumans, Integer numOfComputers, Boolean isAutoDice) {
	// Verify that the Monopoly Game Object is Initialized		
	if (monopolyGame == null) {
	    monopolyGame = new MonopolyGame();
	}
	// Load the Game		
	monopolyGame.loadGame(gameName, numOfHumans, numOfComputers, isAutoDice);
	// Initialize the Game Squares		
	monopolyGame.initGameSquares();
    }

    /**
     * Create the Game In the Server and Initialize all the necessary Objects
     * @param request
     *	    The HTTP Request that holds the Game Parameters
     */
    private void createGame(HttpServletRequest request) {
	// Set the game Details
	String gameName = request.getParameter(GAME_NAME);
	Integer numOfHumans = getInt(request.getParameter(NUM_OF_HUMANS));
	Integer numOfPlayers = getInt(request.getParameter(NUM_OF_PLAYERS));
	Boolean diceMode = getDiceMode(request.getParameter(AUTO_DICE_MODE));
	// Initialize the Monopoly Game
//	monopolyGame = new MonopolyGame();
	// Start a Game - Usually in Waiting State
	try {
	    // Get the Number of Computer Players in the Game
	    Integer numOfComputers = numOfPlayers - numOfHumans;
	    // Create the Game
	    ServerService.getInstance().startGame(gameName, numOfHumans, numOfComputers, diceMode);
	    // Load the Game
	    loadMonopolyGame(gameName, numOfHumans, numOfComputers, diceMode);
//	    monopolyGame.loadGame(gameName, numOfHumans, numOfPlayers - numOfHumans, diceMode);
	    // Initialize the Game Squares
//	    monopolyGame.initGameSquares();
	    // Set the variable gameDetails with the current Game Details
	    getGameDetails();
	    if (checkPosibleStart()) {
		// Initialize the Events
		events = null;
		// Get the First Events
		events = Collections.synchronizedList(MonopolyGameEvents.getInstance().getEvents());
	    }
	} catch (MonopolErrors e) {
	    // Print the Stack Trace
	    e.printStackTrace();
	}
    }

    /**
     * Check the Availability of the Game to Start
     *
     * @return True if the Game can Begin, False Otherwise
     */
    private boolean checkPosibleStart() {
	if (gameDetails.getTotalHumanPlayers() == gameDetails.getJoinedHumans()) {
	    // All the Human Players Have Joined
	    // The Game can Begin!
	    return true;
	} else {
	    // No All the Human Players have Joined
	    // Waiting for other Players to Join
	    return false;
	}
    }

    /**
     * Checks if the User has a valid Player ID or not
     * @param session
     *	    The User HTTP Session
     * @return
     *	    True if th User has a Valid Player Session ID
     *	    False Otherwise
     */
    private Boolean checkPlayerSession(HttpSession session) {
	WebClientInformation clientSession = (WebClientInformation) session.getAttribute(PLAYER_ID);
	// Check the if the User has a valid Player ID
	if (clientSession != null
		&& clientSession.playerID != -1) {
	    return true;
	} else {
	    return false;
	}

    }


    /**
     * Sends an Error message to the Page
     *
     * @param request
     *            The Http Servlet Request
     * @param response
     *            The Http Servlet Response
     * @param msg
     *            The message to Send
     * @throws IOException
     */
    public void sendError(HttpServletRequest request,
	    HttpServletResponse response, String msg) throws IOException {
	PrintWriter out = response.getWriter();
	try {
	    out.println(msg);
	    response.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
	} finally {
	    out.close();
	}
    }

    /**
     * Forwards the Request to the Load Game Page
     *
     * @param request
     *            The Http Servlet Request
     * @param response
     *            The Http Servlet Response
     * @throws ServletException
     * @throws IOException
     */
    private void forwardToLoadPage(HttpServletRequest request,
	    HttpServletResponse response, String... errorMessage)
	    throws ServletException, IOException {
	response.setContentType(CONTENT_TYPE_TEXT);
	response.setHeader("pragma-", "no-cache");
	// Forward the Page to the Creation Page
	RequestDispatcher view = request.getRequestDispatcher(GAME_LOADER_PAGE);
	view.forward(request, response);
    }

    /**
     * Forwards the Request to the Join Game Page
     *
     * @param request
     *            The Http Servlet Request
     * @param response
     *            The Http Servlet Response
     * @throws ServletException
     * @throws IOException
     */
    private void forwardToJoinPage(HttpServletRequest request,
	    HttpServletResponse response, String... errorMessage)
	    throws ServletException, IOException {
	response.setContentType(CONTENT_TYPE_TEXT);
	response.setHeader("pragma-", "no-cache");
	// Set the Return Parameters
	request.setAttribute(GAME_NAME, gameDetails.getGameName());
	request.setAttribute(NUM_OF_PLAYERS, gameDetails.getTotalPlayers());
	request.setAttribute(NUM_OF_HUMANS,
		gameDetails.getTotalHumanPlayers());
	request.setAttribute(AUTO_DICE_MODE,
		gameDetails.isAutomaticDiceRoll());
	request.setAttribute(JOINED_HUMANS, gameDetails.getJoinedHumans());
	// Check if there are any errors to Send
	if (errorMessage != null) {
	    request.setAttribute(ERROR_MESSAGE, errorMessage);
	}
	// Forward the Page the the Join Page
	RequestDispatcher view = request.getRequestDispatcher(GAME_JOIN_PAGE);
	view.forward(request, response);

    }

    /**
     * Forwards the Request to the Play Game Page
     *
     * @param request
     *            The Http Servlet Request
     * @param response
     *            The Http Servlet Response
     * @throws ServletException
     * @throws IOException
     */
    private void forwardToPlayGame(HttpServletRequest request,
	    HttpServletResponse response, String playerName, String... errorMessage)
	    throws ServletException, IOException {
	response.setContentType(CONTENT_TYPE_JSON);
	response.setHeader("pragma-", "no-cache");
	try {
	    // Set the Response Attributes
	    request.setAttribute("squares", monopolyGame.getGameSquares());
	    request.setAttribute("playerName", playerName);
	} catch (Exception e) {
	    System.out.println("The Squares Array is Null");
	}
	// Forward the Page to the Playing Page
	RequestDispatcher view = request.getRequestDispatcher(GAME_PLAY_PAGE);
	view.forward(request, response);
    }

    /**
     * Helper Function to Convert a String to Integer without Errors
     *
     * @param strInt
     *            The String Integer to Convert
     * @return The Converted Integer
     */
    private Integer getInt(String strInt) {
	Integer retInt;
	try {
	    retInt = Integer.parseInt(strInt);
	} catch (NumberFormatException e) {
	    retInt = -1;
	}
	return retInt;
    }

    /**
     * Get the Requested Dice Mode
     * @param diceMode
     *	    The Players Dice Mode from the Web Browser
     * @return
     *	    True - If Auto Dice Mode is On
     *	    False - Otherwise
     */
    private Boolean getDiceMode(String diceMode) {
	// Check if the dice Mode is on
	if (diceMode != null && diceMode.equals("on")) {
	    // If dice mode is On - This Means Using Automatic Dice Mode
	    return true;
	} else {
	    // If dice mode is Off - This Means Using Manual Dice Mode
	    return false;
	}
    }

    /**
     * Get the Answer Result from String to Boolean
     * @param playerAnswer
     *	    The Answer to Parse
     * @return
     *	    The Return Value in Boolean
     */
    private Boolean getAnswerResult(String playerAnswer) {
	// Check if the Answer is Yes
	if (playerAnswer != null && playerAnswer.equals("yes")) {
	    return true;
	} else {
	    // The Answer must be No
	    return false;
	}
    }

    /**
     * when a new game was created new JSON array will be created in order to
     * contain new JSON
     */
    public void StartJsonFeed() {
	jEvents = new ArrayList<JSONObject>();

    }

    // when new JSON created it will update the the JSON container here
    // if prompt event occurred info will be collated in matching container
    public static void JsonUpdate(JSONObject newjson) {
	// add new JSON to the jEvents
	jEvents.add(newjson);
    }

    /**
     * Setting the Game End Flag
     */
    public static void setGameEnd() {
	System.out.println("DEBUG: gameEnd is Set!");
	gameEnd = true;
    }

    /**
     * Update the Monopoly Game Events
     */
    private void getServerEvents() {
	final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
	final Lock write = readWriteLock.writeLock();
	// Check that the Game can be played before getting any Events
	if (checkPosibleStart()) {
	    if (events == null || events.isEmpty()) {
		// Get the First Events
		events = Collections.synchronizedList(MonopolyGameEvents.getInstance().getEvents());
	    }
	    synchronized (events) {
		try {
		    write.lock();

		    // Wait before fetching the Events
		    events.wait(200);
		    // Add the New Events
		    events.addAll(MonopolyGameEvents.getInstance().getEvents());
		} catch (InterruptedException ex) {
		    ex.printStackTrace();
		} finally {
		    write.unlock();
		}
	    }
	}
    }

    /**
     * Parse an Event ID to JSON
     * @param eventID
     *	    The Event ID to Parse
     * @return
     *	    The Current Available Event ID
     */
    private Integer parseServerEvent(Integer eventID) {
	final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
	final Lock read = readWriteLock.readLock();
	try {
	    // Check if the Servlet createrd the requested Event
	    if (events.size() > eventID) {
		Event requestedEvent = null;
		read.lock();
		try {
		    requestedEvent = events.get(eventID);
		    // Send the Array to the Monopoly Game Player Parser - Convert to JSON Command
		    monopolyGame.parseEventToJSON(requestedEvent);
		} catch (Exception e) {
		    System.out.println("ERROR: Error Parsing an Event" + e.getMessage());
		    System.out.println("Requested Event ID: " + eventID);
		} finally {
		    read.unlock();
		}
	    } else {//debug : print no event with this number was created
		System.out.println("WARNING: Event index was not created yet");
		return eventID - 1;
	    }
	} catch (Exception e) {
	    e.printStackTrace();
	}
	return eventID;
    }
}
